package org.scau.studentevaluation.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpRequest;
import org.scau.studentevaluation.util.LogConstants;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: x1aolone
 * @Date: 2020/8/19 11:39
 * 打印服务端完成请求消耗的时间
 */

@Slf4j
@Component
public class AccessLogFilter extends ZuulFilter {
    /**
     * 拦截器类型，拦截的主要流程是
     * 请求 => Pre Filters/Custom filters =>
     * Routing Filters [与Origin Server交互完成请求] =>
     * (Error Filters =>) Post Filters => 答复请求
     * 可选用的TYPE参考FilterConstants中的常量
     * ERROR_TYPE、POST_TYPE、PRE_TYPE、ROUTE_TYPE
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    /**
     * zuul 组件默认的 response filter 的 order 是 1000
     * 因为zuul的FilterConstants.SEND_RESPONSE_FILTER_ORDER就是1000
     * 所以我们的 response 过滤器的 order要在
     * FilterConstants.SEND_RESPONSE_FILTER_ORDER 之前，否则不起作用。
     * @return
     */
    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
    }

    /**
     * 是否开启该拦截器
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * RequestContext，用于在过滤器之间传递消息, 它的数据保存在每个请求的 ThreadLocal中
     * 请求路由到哪里、错误、HttpServletRequest、HttpServletResponse都存储在 RequestContext中
     * RequestContext 扩展了 ConcurrentHashMap,所以任何数据都可以存储在上下文中。
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        // 计算持续时间
        Long startTime = (Long)requestContext.get(LogConstants.START_TIME_Millis);
        Long endTime = System.currentTimeMillis();
        Long duration = endTime - startTime;
        // 获取uri
        HttpServletRequest request = requestContext.getRequest();
        String uri = request.getRequestURI();
        log.info("uri: " + uri + ", duration: " + duration + "ms");
        return null;
    }
}
